#include "mineclean.h"
#include "ui_mineclean.h"

//定义全局变量
static int paint_flag = 0;
//根据paint_flag值绘制不同的界面，
//0是初始化时，2是左键点到空白后显示，3是右键点击，4是游戏失败（左键点到雷），5是胜利

QPainter * paintmywindow;
mineclean * app;

//初始化类（雷区行、列、雷的个数）
int ROW =9,COL =9,BOOMNUM = 10;

block * mine = new block(ROW,COL,BOOMNUM);
int click_x,click_y,end = 0;
int LENGTH=mine->getcol()*21;
int HEIGHT=mine->getrow()*21 + TITILE_HEIGHT;
static bool showimage = 1;//决定胜利时输出画面

mineclean::mineclean(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::mineclean)
{
    //构建窗口大小
    app = this;
    ui->setupUi(this);
    this->setMinimumSize(LENGTH,HEIGHT);
    this->setMaximumSize(LENGTH,HEIGHT);
    runtime = new QTimer(this);
}

mineclean::~mineclean(){
    delete ui;
}

//鼠标事件
void mineclean::mousePressEvent(QMouseEvent *event){
    //用户鼠标点击，判断左右键，确定落点，修改块信息，确定是否结束
    click_x = event->x();
    click_y = event->y();

    if(end==1)
        return;

    //确定落点
    click_x = click_x/BLOCK_LENGTH;
    click_y = (click_y-TITILE_HEIGHT)/BLOCK_HEIGHT;

    if(event->buttons()==(Qt::LeftButton)){
        //左键事件
        if(mine->p[click_y][click_x]==99){
            //若点击了炸弹,瞬间爆炸，结束游戏
            paint_flag = 4;
            end = 1;
            runtime->stop();
            update();

        }
        else if((mine->p[click_y][click_x]<10)){
            //需要递归遍历，更改类中信息
            showblock(click_y,click_x);//递归函数
            paint_flag = 2;
            if(end = iswin()==1){
                paint_flag = 5;
                runtime->stop();
            }
            update();
            if(end){
                //结束弹东西
                if(showimage){
                     QMessageBox message(QMessageBox::NoIcon, "你赢啦！！", "比个心奖励你");
                     message.setIconPixmap(QPixmap("win.jpg"));
                     showimage = !showimage;
                     message.exec();
                 }
                else{
                     QMessageBox message(QMessageBox::NoIcon, "你又赢啦！！", "向扫雷大师salute");
                     message.setIconPixmap(QPixmap("good.jpg"));
                     showimage = !showimage;
                     message.exec();
                }
            }
            else
                return;
        }
    }


    else if(event->buttons()==(Qt::RightButton)){
        //右键事件
        if((mine->p[click_y][click_x]<10)||(mine->p[click_y][click_x]==99)) {
            mine->p[click_y][click_x] +=50;//变成插旗状态
            mine->minusredFlagNum();
        }
        else if((mine->p[click_y][click_x]>=50&&mine->p[click_y][click_x]<60)||(mine->p[click_y][click_x]>110)){
            mine->p[click_y][click_x] -=50;//拔旗
            mine->addredFlagNum();
        }
        paint_flag = 3;
        if(end = iswin()==1){
            paint_flag = 5;
            runtime->stop();
        }
        update();
        if(end){
            if(showimage){
                 QMessageBox message(QMessageBox::NoIcon, "你赢啦！！", "比个心奖励你");
                 message.setIconPixmap(QPixmap("win.jpg"));
                 showimage = !showimage;
                 message.exec();
             }
            else{
                 QMessageBox message(QMessageBox::NoIcon, "你又赢啦！！", "向扫雷大师salute");
                 message.setIconPixmap(QPixmap("good.jpg"));
                 showimage = !showimage;
                 message.exec();
            }
        }
    }
}

//绘图事件
void mineclean::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    paintmywindow = &painter;

    //加载图片
    QPixmap block_close("./block_close.bmp");
    QPixmap block_open("./block_open.bmp");
    QPixmap red_flag("./redflag.bmp");
    QPixmap keil_boom("./keilboom.bmp");
    QPixmap click_boom("./clickboom.bmp");
    QPixmap boom("./boom.bmp");
    QPixmap qq_smile("./smile.bmp");
    QPixmap qq_lose("./lose.bmp");
    QPixmap qq_pround("./proud.bmp");  
    QPixmap blk_1("./blk1.bmp");
    QPixmap blk_2("./blk2.bmp");
    QPixmap blk_3("./blk3.bmp");
    QPixmap blk_4("./blk4.bmp");
    QPixmap blk_5("./blk5.bmp");
    QPixmap blk_6("./blk6.bmp");
    QPixmap blk_7("./blk7.bmp");
    QPixmap blk_8("./blk8.bmp");

    //如果是第一次打开，则进行初始化
    if(paint_flag==0)
    {

        //绘制雷区（block_close代表未翻开的格子图片）
        for(int i = 0;i<mine->getcol()*BLOCK_LENGTH;i=i+BLOCK_LENGTH)
            for(int j =TITILE_HEIGHT;j<TITILE_HEIGHT+mine->getrow()*BLOCK_HEIGHT;j=j+BLOCK_HEIGHT)
                painter.drawPixmap(i,j,block_close,0,0,BLOCK_LENGTH,BLOCK_LENGTH);
    }
    //左键点到空白绘制
    else if (paint_flag == 2 )
    {

        //绘制雷区
        paintboom(paintmywindow);
    }
    //右键点击绘制
    else if(paint_flag ==3)
    {


        paintboom(paintmywindow);
    }
    //左键点到炸弹绘制
    else if (paint_flag == 4)
    {

        //绘制雷区
        for(int i = 0;i<mine->getrow();i++)
        {
            for(int j = 0;j<mine->getcol();j++ )
            {
                if((mine->p[i][j]<10))//未翻开的统一格子
                {
                    painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,block_close,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);
                }
                else if((mine->p[i][j]==99))//未点到的其余雷翻开
                {
                    painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,boom,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);
                }
                else if (mine->p[i][j]>110)//插红旗的雷
                {
                    painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,red_flag,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);
                }
                else if ((mine->p[i][j]<60)&&(mine->p[i][j]>=50))//插红旗的非雷格子（标记错的）
                {
                    painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,keil_boom,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);
                }
                else if ((mine->p[i][j])>99&&(mine->p[i][j]<110))//已翻开的
                {
                    int blk_num = mine->p[i][j] - 100;
                    switch (blk_num)
                    {
                    case 0: painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,block_open,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                    case 1: painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_1,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                    case 2: painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_2,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                    case 3: painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_3,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                    case 4: painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_4,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                    case 5: painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_5,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                    case 6: painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_6,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                    case 7: painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_7,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                    case 8: painter.drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_8,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                    }
                }
            }
        }
        //绘制点击的炸弹
        painter.drawPixmap(click_x*BLOCK_LENGTH,click_y*BLOCK_HEIGHT+TITILE_HEIGHT,click_boom,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);

    }

    //游戏成功结束
    else if(paint_flag == 5)
    {

        paintboom(paintmywindow);
    }
}

void showblock(int x,int y){
    //向该格子的周围八个格子递归
    for(int blockRow = x - 1; blockRow <=x + 1;blockRow++)
        for(int blockCol = y - 1;blockCol <=y + 1;blockCol++){
            if(blockRow<0||blockCol<0||blockRow>=mine->getrow()||blockCol>=mine->getcol())//处理一下边界判断
                continue;
            if(mine->p[blockRow][blockCol]<10){// <10为未翻开的数字格子
                mine->p[blockRow][blockCol] =  mine->p[blockRow][blockCol] + 100;//变成翻开状态
                if(mine->p[blockRow][blockCol]==100)
                    showblock(blockRow,blockCol);//100是翻开的空格子
            }
        }
}

//判断输赢函数
int iswin(){
    int cnt = 0;//cnt用来计数
    for(int row = 0; row <mine->getrow();row++)
        for(int col =0;col<mine->getcol();col++){
            if((mine->p[row][col]>=100)&&(mine->p[row][col]<110))
                cnt++;
        }
    if(cnt>=((mine->getcol()*mine->getrow())-mine->getboomNum()))//已翻开的格子>=格子数-雷数
        return 1;
    else
        return 0;
}

//绘制正常鼠标点击事件与结束的雷区
void paintboom(QPainter * painter)
{
    //加载图片
    QPixmap block_close("./block_close.bmp");
    QPixmap block_open("./block_open.bmp");
    QPixmap red_flag("./redflag.bmp");
    QPixmap keil_boom("./keilboom.bmp");
    QPixmap click_boom("./clickboom.bmp");
    QPixmap boom("./boom.bmp");
    QPixmap qq_smile("./smile.bmp");
    QPixmap qq_lose("./lose.bmp");
    QPixmap qq_pround("./proud.bmp");
    QPixmap blk_1("./blk1.bmp");
    QPixmap blk_2("./blk2.bmp");
    QPixmap blk_3("./blk3.bmp");
    QPixmap blk_4("./blk4.bmp");
    QPixmap blk_5("./blk5.bmp");
    QPixmap blk_6("./blk6.bmp");
    QPixmap blk_7("./blk7.bmp");
    QPixmap blk_8("./blk8.bmp");

    for(int i = 0;i<mine->getrow();i++)
    {
        for(int j = 0;j<mine->getcol();j++ )
        {

            if((mine->p[i][j]<10)||(mine->p[i][j]==99))
            {
                painter->drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,block_close,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);
            }
            else if (((mine->p[i][j]<60)&&(mine->p[i][j]>=50))||(mine->p[i][j]>120))
            {
                painter->drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,red_flag,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);
            }
            else if ((mine->p[i][j]>99)&&(mine->p[i][j]<110))
            {
                int blk_num = mine->p[i][j] - 100;
                switch (blk_num)
                {
                case 0: painter->drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,block_open,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                case 1: painter->drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_1,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                case 2: painter->drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_2,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                case 3: painter->drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_3,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                case 4: painter->drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_4,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                case 5: painter->drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_5,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                case 6: painter->drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_6,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                case 7: painter->drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_7,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                case 8: painter->drawPixmap(j*BLOCK_LENGTH,i*BLOCK_HEIGHT+TITILE_HEIGHT,blk_8,0,0,BLOCK_LENGTH,BLOCK_HEIGHT);break;
                }
            }
        }
    }
}

void mineclean::on_actionPrimary_triggered()
{
    paint_flag=0;
    end =0;
    mine = new block(9,9,10);
    LENGTH=mine->getcol()*21;
    HEIGHT=mine->getrow()*21 + TITILE_HEIGHT;
    this->setMinimumSize(LENGTH,HEIGHT);
    this->setMaximumSize(LENGTH,HEIGHT);
    update();
}

void mineclean::on_actionMiddle_triggered()
{
    paint_flag=0;
    end =0;
    mine = new block(16,16,40);
    LENGTH=mine->getcol()*21;
    HEIGHT=mine->getrow()*21 + TITILE_HEIGHT;
    this->setMinimumSize(LENGTH,HEIGHT);
    this->setMaximumSize(LENGTH,HEIGHT);
    update();

}

void mineclean::on_actionSenior_triggered()
{
    paint_flag=0;
    end =0;
    mine = new block(16,30,99);
    LENGTH=mine->getcol()*21;
    HEIGHT=mine->getrow()*21 + TITILE_HEIGHT;
    this->setMinimumSize(LENGTH,HEIGHT);
    this->setMaximumSize(LENGTH,HEIGHT);
    update();
}

void mineclean::on_actionUser_defined_triggered()
{
    useDefineWindows = new Dialog(this);
    useDefineWindows->show();
    update();
}

void createinterface()
{
    paint_flag=0;
    end =0;
    mine = new block(ROW,COL,BOOMNUM);
    LENGTH=mine->getcol()*21;
    HEIGHT=mine->getrow()*21 + TITILE_HEIGHT;
    app->setMinimumSize(LENGTH,HEIGHT);
    app->setMaximumSize(LENGTH,HEIGHT);
}

void mineclean::on_actionRandom_triggered()
{
    paint_flag=0;
    end =0;
    int randrow,randcol,randboom;
    srand((unsigned)time(0));
    randrow=rand()%8+9; randcol=rand()%22+9; randboom=rand()%90+10;
    mine = new block(randrow,randcol,randboom);
    LENGTH=mine->getcol()*21;
    HEIGHT=mine->getrow()*21 + TITILE_HEIGHT;
    app->setMinimumSize(LENGTH,HEIGHT);
    app->setMaximumSize(LENGTH,HEIGHT);
    update();
}

void mineclean::on_actionQuit_2_triggered()
{
    QApplication::quit();
}

void mineclean::on_actionRestart_triggered()
{
    paint_flag=0;
    end =0;
    mine = new block (mine->getrow(),mine->getcol(),mine->getboomNum());
    update();
}
